import {
  ArgumentsHost,
  BadRequestException,
  Catch,
  ExceptionFilter,
  HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { I18nService, I18nValidationException } from 'nestjs-i18n';

// 自定义过滤器处理异常
@Catch(HttpException)
export class AdminExceptionFilters implements ExceptionFilter {
  constructor(private readonly i18n: I18nService) {}

  catch(exception: any, host: ArgumentsHost): any {
    const ctx = host.switchToHttp();
    const request: any = ctx.getRequest<Request>();
    const response = ctx.getResponse<Response>();
    let status = exception.getStatus();
    let message = exception.message;
    // 如果exception是验证管道的类
    if (exception instanceof BadRequestException) {
      const exceptionBody: any = exception.getResponse();
      if (typeof exceptionBody === 'object' && exceptionBody.message) {
        message = exceptionBody.message.join(',');
        status = exceptionBody.statusCode;
      }
    } else if (exception instanceof I18nValidationException) {
      //如果是i18n的类，i18n的异常走一下程序
      const errors = exception.errors;
      message = errors
        .map((error) => this.formatErrorsMessage(error, request.i18nLang))
        .join('\n');
    }
    // 渲染一个hbs模板error
    response.status(status).render('error', {
      message,
    });
  }
  formatErrorsMessage(error, lang) {
    const { constraints, value, property } = error;
    const constraintsValues = Object.values(constraints);
    return (
      `${property}:${value}\n` +
      constraintsValues
        .map((constraintsValue: string) => {
          const [key, params] = constraintsValue.split('|');
          if (params) {
            const parsedParams = JSON.parse(params);
            return (
              '-' +
              this.i18n.translate(key, {
                lang: lang,
                args: parsedParams,
              })
            );
          } else {
            return '-' + key;
          }
        })
        .join('\n')
    );
  }
}
